查看原文
其他

Pandas日期数据处理:如何按日期筛选、显示及统计数据

LEMON Python数据之道 2022-04-24

前言

pandas有着强大的日期数据处理功能,本期我们来了解下pandas处理日期数据的一些基本功能,主要包括以下三个方面:

  • 按日期筛选数据

  • 按日期显示数据

  • 按日期统计数据

运行环境为 windows系统,64位,python3.5。

1 读取并整理数据

  • 首先引入pandas库

  1. import pandas as pd

  • 从csv文件中读取数据

  1. df = pd.read_csv('date.csv', header=None)

  2. print(df.head(2))

  1.            0  1

  2. 0  2013-10-24  3

  3. 1  2013-10-25  4

  • 整理数据

  1. df.columns = ['date','number']

  2. df['date'] = pd.to_datetime(df['date']) #将数据类型转换为日期类型

  3. df = df.set_index('date') # 将date设置为index

  4. print(df.head(2))

  5. print(df.tail(2))

  6. print(df.shape)

  1.            number

  2. date              

  3. 2013-10-24       3

  4. 2013-10-25       4

  5.            number

  6. date              

  7. 2017-02-14       6

  8. 2017-02-22       6

  9. (425, 1)

  • df的行数一共是425行。

查看Dataframe的数据类型

  1. print(type(df))

  2. print(df.index)

  3. print(type(df.index))

  1. <class 'pandas.core.frame.DataFrame'>

  2. DatetimeIndex(['2013-10-24', '2013-10-25', '2013-10-29', '2013-10-30',

  3.               '2013-11-04', '2013-11-06', '2013-11-08', '2013-11-12',

  4.               '2013-11-14', '2013-11-25',

  5.               ...

  6.               '2017-01-03', '2017-01-07', '2017-01-14', '2017-01-17',

  7.               '2017-01-23', '2017-01-25', '2017-01-26', '2017-02-07',

  8.               '2017-02-14', '2017-02-22'],

  9.              dtype='datetime64[ns]', name='date', length=425, freq=None)

  10. <class 'pandas.tseries.index.DatetimeIndex'>

构造Series类型数据

  1. s = pd.Series(df['number'], index=df.index)

  2. print(type(s))

  3. s.head(2)

  1. <class 'pandas.core.series.Series'>

  2. date

  3. 2013-10-24    3

  4. 2013-10-25    4

  5. Name: number, dtype: int64

2 按日期筛选数据

按年度获取数据

  1. print('---------获取2013年的数据-----------')

  2. print(df['2013'].head(2)) # 获取2013年的数据

  3. print(df['2013'].tail(2)) # 获取2013年的数据

  1. ---------获取2013年的数据-----------

  2.            number

  3. date              

  4. 2013-10-24       3

  5. 2013-10-25       4

  6.            number

  7. date              

  8. 2013-12-27       2

  9. 2013-12-30       2

获取2016至2017年的数据

  1. print('---------获取2016至2017年的数据-----------')

  2. print(df['2016':'2017'].head(2))  #获取2016至2017年的数据

  3. print(df['2016':'2017'].tail(2))  #获取2016至2017年的数据

  1. ---------获取20162017年的数据-----------

  2.            number

  3. date              

  4. 2016-01-04       4

  5. 2016-01-07       6

  6.            number

  7. date              

  8. 2017-02-14       6

  9. 2017-02-22       6

获取某月的数据

  1. print('---------获取某月的数据-----------')

  2. print(df['2013-11']) # 获取某月的数据

  1. ---------获取某月的数据-----------

  2.            number

  3. date              

  4. 2013-11-04       1

  5. 2013-11-06       3

  6. 2013-11-08       1

  7. 2013-11-12       5

  8. 2013-11-14       2

  9. 2013-11-25       1

  10. 2013-11-29       1

获取具体某天的数据

  • 请注意dataframe类型的数据,获取具体某天的数据时,跟series是有些差异的,详细情况如下述代码所示:

  1. # 按日期筛选数据

  2. print('---------获取具体某天的数据-----------')

  3. # 获取具体某天的数据

  4. print(s['2013-11-06'])

  5. # 获取具体某天的数据,用datafrme直接选取某天时会报错,而series的数据就没有问题

  6. # print(df['2013-11-06'])

  7. #可以考虑用区间来获取某天的数据

  8. print(df['2013-11-06':'2013-11-06'])

  1. ---------获取具体某天的数据-----------

  2. 3

  3.            number

  4. date              

  5. 2013-11-06       3

  • dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据

  • 但一般建议直接用切片(slice),这样更为直观,方便

  1. # dataframe的truncate函数可以获取某个时期之前或之后的数据,或者某个时间区间的数据

  2. # 但一般建议直接用切片(slice),这样更为直观,方便

  3. print('---------获取某个时期之前或之后的数据-----------')

  4. print('--------after------------')

  5. print(df.truncate(after = '2013-11'))

  6. print('--------before------------')

  7. print(df.truncate(before='2017-02'))

  1. ---------获取某个时期之前或之后的数据-----------

  2. --------after------------

  3.            number

  4. date              

  5. 2013-10-24       3

  6. 2013-10-25       4

  7. 2013-10-29       2

  8. 2013-10-30       1

  9. --------before------------

  10.            number

  11. date              

  12. 2017-02-07       8

  13. 2017-02-14       6

  14. 2017-02-22       6

3 按日期显示数据

3.1 to_period()方法

  • 请注意df.index的数据类型是DatetimeIndex;

  • df_peirod的数据类型是PeriodIndex

按月显示,但不统计

  1. df_period = df.to_period('M') #按月显示,但不统计

  2. print(type(df_period))

  3. print(type(df_period.index))

  4. # 请注意df.index的数据类型是DatetimeIndex;

  5. # df_peirod的数据类型是PeriodIndex

  6. print(df_period.head())

  1. <class 'pandas.core.frame.DataFrame'>

  2. <class 'pandas.tseries.period.PeriodIndex'>

  3.         number

  4. date          

  5. 2013-10       3

  6. 2013-10       4

  7. 2013-10       2

  8. 2013-10       1

  9. 2013-11       1

按季度显示,但不统计

  1. print(df.to_period('Q').head()) #按季度显示,但不统计

  1.        number

  2. date          

  3. 2013Q4       3

  4. 2013Q4       4

  5. 2013Q4       2

  6. 2013Q4       1

  7. 2013Q4       1

按年度显示,但不统计

  1. print(df.to_period('A').head()) #按年度显示,但不统计

  1.      number

  2. date        

  3. 2013       3

  4. 2013       4

  5. 2013       2

  6. 2013       1

  7. 2013       1

3.2 asfreq()方法

按年度频率显示

  1. df_period.index.asfreq('A') # 'A'默认是'A-DEC',其他如'A-JAN'

  1. PeriodIndex(['2013', '2013', '2013', '2013', '2013', '2013', '2013', '2013',

  2.             '2013', '2013',

  3.             ...

  4.             '2017', '2017', '2017', '2017', '2017', '2017', '2017', '2017',

  5.             '2017', '2017'],

  6.            dtype='period[A-DEC]', name='date', length=425, freq='A-DEC')

  1. df_period.index.asfreq('A-JAN') # 'A'默认是'A-DEC',其他如'A-JAN'

  1. PeriodIndex(['2014', '2014', '2014', '2014', '2014', '2014', '2014', '2014',

  2.             '2014', '2014',

  3.             ...

  4.             '2017', '2017', '2017', '2017', '2017', '2017', '2017', '2018',

  5.             '2018', '2018'],

  6.            dtype='period[A-JAN]', name='date', length=425, freq='A-JAN')

  • 按年度频率在不同情形下的显示,可参考下图所示:

按季度频率显示

  1. df_period.index.asfreq('Q') # 'Q'默认是'Q-DEC',其他如“Q-SEP”,“Q-FEB”

  1. PeriodIndex(['2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4', '2013Q4',

  2.             '2013Q4', '2013Q4', '2013Q4', '2013Q4',

  3.             ...

  4.             '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1', '2017Q1',

  5.             '2017Q1', '2017Q1', '2017Q1', '2017Q1'],

  6.            dtype='period[Q-DEC]', name='date', length=425, freq='Q-DEC')

  1. df_period.index.asfreq('Q-SEP') # 可以显示不同的季度财年,“Q-SEP”,“Q-FEB”

  2. # df_period.index = df_period.index.asfreq('Q-DEC') # 可以显示不同的季度财年,“Q-SEP”,“Q-FEB”

  3. # print(df_period.head())

  1. PeriodIndex(['2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1', '2014Q1',

  2.             '2014Q1', '2014Q1', '2014Q1', '2014Q1',

  3.             ...

  4.             '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2', '2017Q2',

  5.             '2017Q2', '2017Q2', '2017Q2', '2017Q2'],

  6.            dtype='period[Q-SEP]', name='date', length=425, freq='Q-SEP')

  • 按季度频率在不同情形下的显示,可参考下图所示:

按月度频率显示

  1. df_period.index.asfreq('M') # 按月份显示

  1. PeriodIndex(['2013-10', '2013-10', '2013-10', '2013-10', '2013-11', '2013-11',

  2.             '2013-11', '2013-11', '2013-11', '2013-11',

  3.             ...

  4.             '2017-01', '2017-01', '2017-01', '2017-01', '2017-01', '2017-01',

  5.             '2017-01', '2017-02', '2017-02', '2017-02'],

  6.            dtype='period[M]', name='date', length=425, freq='M')

按工作日显示

  • method 1

  1. df_period.index.asfreq('B', how='start') # 按工作日期显示

  1. PeriodIndex(['2013-10-01', '2013-10-01', '2013-10-01', '2013-10-01',

  2.             '2013-11-01', '2013-11-01', '2013-11-01', '2013-11-01',

  3.             '2013-11-01', '2013-11-01',

  4.             ...

  5.             '2017-01-02', '2017-01-02', '2017-01-02', '2017-01-02',

  6.             '2017-01-02', '2017-01-02', '2017-01-02', '2017-02-01',

  7.             '2017-02-01', '2017-02-01'],

  8.            dtype='period[B]', name='date', length=425, freq='B')

  • method 2

  1. df_period.index.asfreq('B', how='end') # 按工作日期显示

  1. PeriodIndex(['2013-10-31', '2013-10-31', '2013-10-31', '2013-10-31',

  2.             '2013-11-29', '2013-11-29', '2013-11-29', '2013-11-29',

  3.             '2013-11-29', '2013-11-29',

  4.             ...

  5.             '2017-01-31', '2017-01-31', '2017-01-31', '2017-01-31',

  6.             '2017-01-31', '2017-01-31', '2017-01-31', '2017-02-28',

  7.             '2017-02-28', '2017-02-28'],

  8.            dtype='period[B]', name='date', length=425, freq='B')

4 按日期统计数据

4.1按日期统计数据

按周统计数据

  1. print(df.resample('w').sum().head())

  2. # “w”,week

  1.            number

  2. date              

  3. 2013-10-27     7.0

  4. 2013-11-03     3.0

  5. 2013-11-10     5.0

  6. 2013-11-17     7.0

  7. 2013-11-24     NaN

按月统计数据

  1. print(df.resample('M').sum().head())

  2. # "MS"是每个月第一天为开始日期, "M"是每个月最后一天

  1.            number

  2. date              

  3. 2013-10-31      10

  4. 2013-11-30      14

  5. 2013-12-31      27

  6. 2014-01-31      16

  7. 2014-02-28       4

按季度统计数据

  1. print(df.resample('Q').sum().head())

  2. # "QS"是每个季度第一天为开始日期, "Q"是每个季度最后一天

  1.            number

  2. date              

  3. 2013-12-31      51

  4. 2014-03-31      73

  5. 2014-06-30      96

  6. 2014-09-30     136

  7. 2014-12-31     148

按年统计数据

  1. print(df.resample('AS').sum())

  2. # "AS"是每年第一天为开始日期, "A是每年最后一天

  1.            number

  2. date              

  3. 2013-01-01      51

  4. 2014-01-01     453

  5. 2015-01-01     743

  6. 2016-01-01    1552

  7. 2017-01-01      92

  • 关于日期的类型,按参考下图所示来选择合适的分期频率:

4.2 按日期统计后,按年或季度或月份显示

按年统计并显示

  1. print(df.resample('AS').sum().to_period('A'))

  2. # 按年统计并显示

  1.      number

  2. date        

  3. 2013      51

  4. 2014     453

  5. 2015     743

  6. 2016    1552

  7. 2017      92

按季度统计并显示

  1. print(df.resample('Q').sum().to_period('Q').head())

  2. # 按季度统计并显示

  1.        number

  2. date          

  3. 2013Q4      51

  4. 2014Q1      73

  5. 2014Q2      96

  6. 2014Q3     136

  7. 2014Q4     148

按月度统计并显示

  1. print(df.resample('M').sum().to_period('M').head())

  2. # 按月度统计并显示

  1.         number

  2. date          

  3. 2013-10      10

  4. 2013-11      14

  5. 2013-12      27

  6. 2014-01      16

  7. 2014-02       4

更多精彩内容请关注微信公众号:

“Python数据之道”





您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存